package utils;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import org.codehaus.jackson.map.ObjectMapper;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author yyh
 *
 * @date 2018/01/18
 *
 * @description 支付配置工具
 */
public class PayUtils {


	private static final Logger log = LoggerFactory.getLogger(PayUtils.class);

	/**
	 * 扩展xstream,使其支持name带有"_"的节点
	 */
	public static XStream xStream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
	public static ObjectMapper jsonObjectMapper = new ObjectMapper();

	/**
	 * 获取微信签名
	 *
	 * @param map
	 * @param api_key
	 * @return
	 */
	public static String getSign(SortedMap<String, Object> map,String api_key) {
		StringBuffer buffer = new StringBuffer();
		Set<Map.Entry<String, Object>> set = map.entrySet();
		Iterator<Map.Entry<String, Object>> iterator = set.iterator();
		while (iterator.hasNext()) {
			Map.Entry<String, Object> entry = iterator.next();
			String k = entry.getKey();
			Object v = entry.getValue();
			// 参数中sign、key不参与签名加密
			if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
				buffer.append(k + "=" + v + "&");
			}
		}
		buffer.append("key=" + api_key);
		String sign = MD5.MD5Encode(buffer.toString()).toUpperCase();
		return sign;
	}

	/**
	 * 构建统一下单参数map 用于生成签名
	 *
	 * @param data
	 * @return
	 */
//	public static SortedMap<String, Object> buildParamMap(PaySendData data) {
//		SortedMap<String, Object> params = new TreeMap<String, Object>();
//		Field[] fields = data.getClass().getDeclaredFields();
//		try {
//			for (Field field : fields) {
//				field.setAccessible(true);
//				if (null != field.get(data)) {
//					params.put(field.getName().toLowerCase(), field.get(data).toString());
//				}
//			}
//		} catch (Exception e) {
//			System.out.print("构建签名map错误: ");
//			e.printStackTrace();
//		}
//		return params;
//	}

	/**
	 * 构建转账参数map 用于生成签名
	 *
	 * @param data
	 * @return
	 */
	public static SortedMap<String, Object> buildParamMap(Object data) {
		SortedMap<String, Object> params = new TreeMap<String, Object>();
		Field[] fields = data.getClass().getDeclaredFields();
		try {
			for (Field field : fields) {
				field.setAccessible(true);
				if (null != field.get(data)) {
					params.put(field.getName().toLowerCase(), field.get(data).toString());
				}
			}
		} catch (Exception e) {
			System.out.print("构建签名map错误: ");
			e.printStackTrace();
		}
		return params;
	}

	/**
	 * 解析微信服务器发来的请求
	 * 
	 * @param inputStream
	 * @return 微信返回的参数集合
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, String> parseXml(InputStream inputStream) {
		SortedMap<String, String> map = new TreeMap<String, String>();
		try {
			// 获取request输入流
			SAXReader reader = new SAXReader();
			Document document = reader.read(inputStream);
			// 得到xml根元素
			Element root = document.getRootElement();
			// 得到根元素所有节点
			List<Element> elementList = root.elements();
			// 遍历所有子节点
			for (Element element : elementList) {
				map.put(element.getName(), element.getText());
			}
			// 释放资源
			inputStream.close();
		} catch (Exception e) {
			log.warn("--Exception--"+e);
			log.warn("--微信工具类:解析xml异常--"+e);
			e.printStackTrace();
			System.out.println("微信工具类:解析xml异常");
		}
		return map;
	}

	/**
	 * 请求参数转换成xml
	 * 
	 * @param data
	 * @return xml字符串
	 */
	public static String sendDataToXml(Object data) {
		xStream.autodetectAnnotations(true);
		xStream.alias("xml", data.getClass());
		return xStream.toXML(data);
	}

	/**
	 * 获取当前时间戳
	 * 
	 * @return 当前时间戳字符串
	 */
	public static String getTimeStamp() {
		return String.valueOf(System.currentTimeMillis() / 1000);
	}

	/**
	 * 获取指定长度的随机字符串
	 * 
	 * @param length
	 * @return 随机字符串
	 */
	public static String getRandomStr(int length) {
		String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}


}
